package com.seafood.service.impl;

import com.seafood.common.PageResult;
import com.seafood.dto.CreateOrderDTO;
import com.seafood.dto.OrderDTO;
import com.seafood.dto.OrderItemDTO;
import com.seafood.dto.OrderStatisticsDTO;
import com.seafood.entity.*;
import com.seafood.exception.BusinessException;
import com.seafood.repository.*;
import com.seafood.service.OrderService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 订单服务实现类
 */
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class OrderServiceImpl implements OrderService {
    
    private final OrderRepository orderRepository;
    private final UserRepository userRepository;
    private final ProductRepository productRepository;
    private final OrderItemRepository orderItemRepository;
    
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
    @Override
    public OrderDTO createOrder(Long userId, CreateOrderDTO createOrderDTO) {
        // 验证用户是否存在
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new BusinessException("用户不存在"));
        
        // 计算订单总金额
        BigDecimal totalAmount = BigDecimal.ZERO;
        
        // 先计算总金额，确保在创建订单时就有值
        for (CreateOrderDTO.OrderItemRequest itemRequest : createOrderDTO.getItems()) {
            Product product = productRepository.findById(itemRequest.getProductId())
                    .orElseThrow(() -> new BusinessException("产品不存在: " + itemRequest.getProductId()));
            
            // 检查库存
            if (product.getStockQuantity() < itemRequest.getQuantity()) {
                throw new BusinessException("产品库存不足: " + product.getName());
            }
            
            // 计算单项金额
            BigDecimal itemTotal = product.getPrice().multiply(BigDecimal.valueOf(itemRequest.getQuantity()));
            totalAmount = totalAmount.add(itemTotal);
        }
        
        // 添加运费到总金额
        BigDecimal shippingFee = createOrderDTO.getShippingFee() != null ? createOrderDTO.getShippingFee() : BigDecimal.ZERO;
        totalAmount = totalAmount.add(shippingFee);
        
        // 创建订单
        Order order = new Order();
        order.setUser(user);
        order.setOrderNumber(generateOrderNumber());
        order.setShippingAddress(createOrderDTO.getShippingAddress());
        order.setRecipientName(createOrderDTO.getRecipientName());
        order.setRecipientPhone(createOrderDTO.getRecipientPhone());
        order.setRemark(createOrderDTO.getRemark());
        order.setStatus(Order.OrderStatus.PENDING);
        order.setTotalAmount(totalAmount);
        order.setShippingFee(shippingFee);
        order.setFinalAmount(totalAmount); // 暂时不考虑优惠
        
        // 保存订单
        Order savedOrder = orderRepository.save(order);
        
        // 创建订单项
        for (CreateOrderDTO.OrderItemRequest itemRequest : createOrderDTO.getItems()) {
            Product product = productRepository.findById(itemRequest.getProductId())
                    .orElseThrow(() -> new BusinessException("产品不存在: " + itemRequest.getProductId()));
            
            OrderItem orderItem = new OrderItem();
            orderItem.setOrder(savedOrder);
            orderItem.setProduct(product);
            orderItem.setProductName(product.getName()); // 设置产品名称
            orderItem.setQuantity(itemRequest.getQuantity());
            orderItem.setUnitPrice(product.getPrice());
            orderItem.setTotalPrice(product.getPrice().multiply(BigDecimal.valueOf(itemRequest.getQuantity())));
            orderItem.setBatchNumber(itemRequest.getBatchNumber());
            
            orderItemRepository.save(orderItem);
            
            // 减少库存
            product.setStockQuantity(product.getStockQuantity() - itemRequest.getQuantity());
            productRepository.save(product);
        }
        
        return convertToDTO(savedOrder);
    }
    
    @Override
    public OrderDTO getOrderById(Long id) {
        Order order = orderRepository.findById(id)
                .orElseThrow(() -> new BusinessException("订单不存在"));
        return convertToDTO(order);
    }
    
    @Override
    public PageResult<OrderDTO> getUserOrders(Long userId, Integer page, Integer size) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new BusinessException("用户不存在"));
        
        Pageable pageable = PageRequest.of(page - 1, size, Sort.by(Sort.Direction.DESC, "createdAt"));
        Page<Order> orderPage = orderRepository.findByUserOrderByCreatedAtDesc(user, pageable);
        
        List<OrderDTO> orderDTOs = orderPage.getContent().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
        
        return PageResult.of(orderDTOs, orderPage.getTotalElements(), orderPage.getTotalPages(), 
                            page - 1, size, orderPage.isFirst(), orderPage.isLast());
    }
    
    @Override
    public PageResult<OrderDTO> getAllOrders(Integer page, Integer size) {
        Pageable pageable = PageRequest.of(page - 1, size, Sort.by(Sort.Direction.DESC, "createdAt"));
        Page<Order> orderPage = orderRepository.findAll(pageable);
        
        List<OrderDTO> orderDTOs = orderPage.getContent().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
        
        return PageResult.of(orderDTOs, orderPage.getTotalElements(), orderPage.getTotalPages(), 
                            page - 1, size, orderPage.isFirst(), orderPage.isLast());
    }
    
    @Override
    public OrderDTO updateOrderStatus(Long orderId, Order.OrderStatus status) {
        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new BusinessException("订单不存在"));
        
        order.setStatus(status);
        
        // 如果状态变为已支付，记录支付时间
        if (status == Order.OrderStatus.PAID) {
            order.setPaymentTime(LocalDateTime.now());
        }
        
        Order savedOrder = orderRepository.save(order);
        return convertToDTO(savedOrder);
    }
    
    @Override
    public void cancelOrder(Long orderId, Long userId) {
        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new BusinessException("订单不存在"));
        
        // 验证订单所有者
        if (!order.getUser().getId().equals(userId)) {
            throw new BusinessException("无权限操作此订单");
        }
        
        // 只有待支付的订单可以取消
        if (order.getStatus() != Order.OrderStatus.PENDING) {
            throw new BusinessException("订单状态不允许取消");
        }
        
        // 恢复库存
        for (OrderItem item : order.getOrderItems()) {
            Product product = item.getProduct();
            product.setStockQuantity(product.getStockQuantity() + item.getQuantity());
            productRepository.save(product);
        }
        
        // 更新订单状态
        order.setStatus(Order.OrderStatus.CANCELLED);
        orderRepository.save(order);
    }
    
    @Override
    public OrderStatisticsDTO getUserOrderStats(Long userId) {
        // 验证用户是否存在
        userRepository.findById(userId)
                .orElseThrow(() -> new BusinessException("用户不存在"));
        
        OrderStatisticsDTO stats = new OrderStatisticsDTO();
        
        // 获取总订单数
        long totalOrders = orderRepository.countByUserId(userId);
        stats.setTotalOrders(totalOrders);
        
        // 获取总消费金额
        BigDecimal totalAmount = orderRepository.sumFinalAmountByUserId(userId);
        if (totalAmount != null) {
            stats.setTotalAmount(totalAmount);
        }
        
        // 获取待支付订单数
        long pendingOrders = orderRepository.countByUserIdAndStatus(userId, Order.OrderStatus.PENDING);
        stats.setPendingOrders(pendingOrders);
        
        // 获取已完成订单数（已支付、已发货、已送达）
        long completedOrders = orderRepository.countByUserIdAndStatusIn(userId, 
                List.of(Order.OrderStatus.PAID, Order.OrderStatus.SHIPPED, Order.OrderStatus.DELIVERED));
        stats.setCompletedOrders(completedOrders);
        
        return stats;
    }
    
    @Override
    public String generateOrderNumber() {
        return "ORD" + System.currentTimeMillis() + String.format("%03d", (int)(Math.random() * 1000));
    }
    
    /**
     * 转换为DTO
     */
    private OrderDTO convertToDTO(Order order) {
        OrderDTO dto = new OrderDTO();
        dto.setId(order.getId());
        dto.setUserId(order.getUser().getId());
        dto.setUserName(order.getUser().getUsername());
        dto.setOrderNumber(order.getOrderNumber());
        dto.setTotalAmount(order.getTotalAmount());
        dto.setShippingFee(order.getShippingFee());
        dto.setDiscountAmount(order.getDiscountAmount());
        dto.setFinalAmount(order.getFinalAmount());
        dto.setStatus(order.getStatus().name());
        dto.setPaymentMethod(order.getPaymentMethod());
        
        if (order.getPaymentTime() != null) {
            dto.setPaymentTime(order.getPaymentTime().format(FORMATTER));
        }
        
        dto.setShippingAddress(order.getShippingAddress());
        dto.setRecipientName(order.getRecipientName());
        dto.setRecipientPhone(order.getRecipientPhone());
        dto.setLogisticsCompany(order.getLogisticsCompany());
        dto.setTrackingNumber(order.getTrackingNumber());
        dto.setRemark(order.getRemark());
        dto.setCreatedAt(order.getCreatedAt().format(FORMATTER));
        dto.setUpdatedAt(order.getUpdatedAt().format(FORMATTER));
        
        // 转换订单项
        if (order.getOrderItems() != null) {
            List<OrderItemDTO> orderItemDTOs = order.getOrderItems().stream()
                    .map(this::convertOrderItemToDTO)
                    .collect(Collectors.toList());
            dto.setOrderItems(orderItemDTOs);
        }
        
        return dto;
    }
    
    /**
     * 转换订单项为DTO
     */
    private OrderItemDTO convertOrderItemToDTO(OrderItem orderItem) {
        OrderItemDTO dto = new OrderItemDTO();
        dto.setId(orderItem.getId());
        dto.setOrderId(orderItem.getOrder().getId());
        dto.setProductId(orderItem.getProduct().getId());
        dto.setProductName(orderItem.getProduct().getName());
        dto.setProductImage(orderItem.getProduct().getImageUrl());
        dto.setQuantity(orderItem.getQuantity());
        dto.setUnitPrice(orderItem.getUnitPrice());
        dto.setTotalPrice(orderItem.getTotalPrice());
        dto.setBatchNumber(orderItem.getBatchNumber());
        // dto.setSpecifications(orderItem.getProduct().getSpecifications()); // Product doesn't have specifications field
        dto.setCreatedAt(orderItem.getCreatedAt().format(FORMATTER));
        
        return dto;
    }
}